package com.program.houai.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.program.houai.entity.*;
import com.program.houai.exception.BusinessException;
import com.program.houai.exception.ErrorType;
import com.program.houai.po.LoginUser;
import com.program.houai.po.UserCardPO;
import com.program.houai.redis.RedisService;
import com.program.houai.service.IBankCardService;
import com.program.houai.service.IMemberCardService;
import com.program.houai.service.IUserService;
import com.program.houai.service.IUserVipCardService;
import com.program.houai.service.impl.MemberCardServiceImpl;
import com.program.houai.util.*;
import com.program.houai.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version v1.0
 * @ProjectName: EOrder-master
 * @ClassName: CardController
 * @Description: TODO(一句话描述该类的功能)
 * @Author: Topcheer
 * @Date: 2024/8/26 19:57
 */
@Api(tags = "VIP会员卡接口")
@RestController
@RequestMapping("/app/vipcard")
@Slf4j
@Validated
public class VipCardController {

    @Autowired
    private IMemberCardService memberCardService;

    @Autowired
    private IUserVipCardService userVipCardService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IUserService userService;
    @Value("${system.file.request-url}")
    private String requestUrl;
    @Value("${system.h5RegistryUrl}")
    private String h5RegistryUrl;

    @Autowired
    private IBankCardService bankCardService;

    @ApiOperation("购买会员卡头部用户信息")
    @PostMapping(value = "/userCardInfo", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<UserCardHeadVO> list(@RequestHeader("token") String token) {

        LoginUser loginUser = redisService.getLoginValueByToken(token);
        UserCardHeadVO userCardHeadVO = new UserCardHeadVO();
        QueryWrapper<UserVipCardEntity> userWrap = new QueryWrapper<UserVipCardEntity>();
        userWrap.eq("user_id", loginUser.getId());
        userWrap.eq("card_status", 0);
        long count = userVipCardService.count(userWrap);
        UserEntity userEntity = userService.getById(loginUser.getId());
        userCardHeadVO.setCount((int) count);
        userCardHeadVO.setUserName(userEntity.getUsername());
        if (StringUtils.isBlank(userEntity.getAvatarUrl())){
            userCardHeadVO.setAvatarUrl(requestUrl+"static/user/avatar.png");
        }else {
            userCardHeadVO.setAvatarUrl(userEntity.getAvatarUrl());
        }
        return R.ok(userCardHeadVO);
    }

    @ApiOperation("会员卡列表")
    @PostMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<PageUtils<MemberCardEntity>> list(@RequestBody PageVO pageVO) {
        IPage<MemberCardEntity> page = new Page<>(pageVO.getPageNum(), pageVO.getPageSize());
        page = memberCardService.getBaseMapper().selectPage(page,null);
        for (MemberCardEntity memberCardEntity:page.getRecords()){
            memberCardEntity.setUrl(requestUrl+"static/buyVip/"+memberCardEntity.getLevel()+".png");
            memberCardEntity.setValidityPeriod(memberCardEntity.getValidityPeriod());
            BigDecimal divisor = BigDecimal.valueOf(100);
            BigDecimal dividend = BigDecimal.valueOf( memberCardEntity.getPrice());
            BigDecimal orderPrice = dividend.divide(divisor, 2, RoundingMode.HALF_UP);
            memberCardEntity.setPriceStr(orderPrice.toString());
        }
        return R.ok(new PageUtils(page));
    }


    @ApiOperation("我的卡包")
    @PostMapping(value = "/myCardlist", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<PageUtils<UserVipCardEntity>> myCardlist(@RequestBody PageVO pageVO,@RequestHeader("token") String token) {
        IPage<UserVipCardEntity> page = new Page<>(pageVO.getPageNum(), pageVO.getPageSize());
        LoginUser loginUser =  redisService.getLoginValueByToken(token);
        UserEntity userEntity = userService.getById(loginUser.getId());
        page = userVipCardService.getCardList(page,loginUser.getId());
        for (UserVipCardEntity userVipCardEntity:page.getRecords()){
            userVipCardEntity.setUrl(requestUrl+"static/buyVip/"+userVipCardEntity.getLevel()+".png");
            BigDecimal divisor = BigDecimal.valueOf(100);
            BigDecimal dividend = BigDecimal.valueOf( userVipCardEntity.getPrice());
            BigDecimal orderPrice = dividend.divide(divisor, 2, RoundingMode.HALF_UP);
            userVipCardEntity.setPriceStr(orderPrice.toString());
            if (StringUtils.isBlank(userEntity.getAvatarUrl())){
                userVipCardEntity.setAvatarUrl(requestUrl+"static/user/avatar.png");
            }else {
                userVipCardEntity.setAvatarUrl(userEntity.getAvatarUrl());
            }
        }
        return R.ok(new PageUtils(page));
    }

    @ApiOperation("我的卡包-新")
    @PostMapping(value = "/myCardlistNew", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<PageUtils<UserVipCardEntity>> myCardlistNew(@RequestBody CardQueryVO pageVO, @RequestHeader("token") String token) {
        LoginUser loginUser =  redisService.getLoginValueByToken(token);
        UserEntity userEntity = userService.getById(loginUser.getId());
        IPage<UserCardPO> page = new Page<>(pageVO.getPageNum(), pageVO.getPageSize());
        page  = userVipCardService.getCardListNew(page,loginUser.getId(),pageVO.getLevel());
        for (UserCardPO  userCardPO : page.getRecords()){
            if (StringUtils.isBlank(userEntity.getAvatarUrl())){
                userCardPO.setAvatarUrl(requestUrl+"static/user/avatar.png");
            }else {
                userCardPO.setAvatarUrl(userEntity.getAvatarUrl());
            }
            BigDecimal divisor = BigDecimal.valueOf(100);
            BigDecimal dividend = BigDecimal.valueOf( userCardPO.getPrice());
            BigDecimal orderPrice = dividend.divide(divisor, 2, RoundingMode.HALF_UP);
            userCardPO.setPriceStr(orderPrice.toString());
            userCardPO.setUrl(requestUrl+"static/buyVip/"+userCardPO.getLevel()+".png");
        }
        return R.ok(new PageUtils(page));
    }


    @ApiOperation("下拉框")
    @PostMapping(value = "/comboxList", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<Map<String, List<ComboxVO>>> ComboxList() {
        List<MemberCardEntity> memberCardEntityList = memberCardService.list();

        List<BankCardEntity>  bankCardEntityList =  bankCardService.list();

        Map<String, List<ComboxVO>> allMap = new HashMap<>();

        List<ComboxVO>  cardList = new ArrayList<>();
        for (MemberCardEntity  memberCardEntity : memberCardEntityList){
            ComboxVO comboxVO = new ComboxVO();
            comboxVO.setCode(memberCardEntity.getLevel()+"");
            comboxVO.setName(memberCardEntity.getName());
            cardList.add(comboxVO);
        }
        allMap.put("cardType",cardList);
        List<ComboxVO>  bankCardList = new ArrayList<>();
        for (BankCardEntity bankCardEntity : bankCardEntityList){
            ComboxVO comboxVO = new ComboxVO();
            comboxVO.setCode(bankCardEntity.getBankCode());
            comboxVO.setName(bankCardEntity.getBankName());
            bankCardList.add(comboxVO);
        }
        allMap.put("bankList",bankCardList);
        return R.ok(allMap);
    }

    @PostMapping("/getZxCode")
    @ApiOperation("会员卡分享二维码")
    public R<ZxCodeVO> getQRCode(@RequestBody BaseVO baseVO) throws IOException, WriterException {
        UserVipCardEntity userVipCardEntity = userVipCardService.getById(baseVO.getId());
        if (userVipCardEntity.getCardStatus() == 1){
            throw new BusinessException(ErrorType.BIZ_ERROR,"该卡已被使用");
        }
        MemberCardEntity memberCardEntity = memberCardService.getById(userVipCardEntity.getCardId());

        String text = h5RegistryUrl+"?cardCode="+userVipCardEntity.getCardCode(); // 二维码内容
        ZxCodeVO zxCodeVO = new ZxCodeVO();
        int width = 200; // 二维码宽度
        int height = 200; // 二维码高度
        String format = "png";
        BitMatrix matrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, width, height,
                getHints());
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(matrix, format, out);
        byte[] imageBytes = out.toByteArray();
        String base64String = Base64.getEncoder().encodeToString(imageBytes);
        zxCodeVO.setBase64Str(base64String);
        zxCodeVO.setUrl(requestUrl+"static/qcCode/"+memberCardEntity.getLevel()+".png");
        return R.ok(zxCodeVO);
    }

    private static java.util.HashMap<EncodeHintType, Object> getHints() {
        java.util.HashMap<EncodeHintType, Object> hints = new java.util.HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        hints.put(EncodeHintType.MARGIN, 2);
        return hints;
    }

    @RequestMapping("/getCode")
    @ApiOperation("小程序分享二维码")
    public void createQRCode(String param, String page, HttpServletResponse response) {
        OutputStream stream = null;
        try {
            //获取AccessToken
            String accessToken = getAccessToken();
            //设置响应类型
            response.setContentType("image/png");
            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;
            //组装参数
            Map<String, Object> paraMap = new HashMap<>();
            //二维码携带参数 不超过32位 参数类型必须是字符串
            paraMap.put("scene", param);
            //二维码跳转页面
            paraMap.put("page", page);
            //二维码的宽度
            paraMap.put("width", 450);
            //自动配置线条颜色，如果颜色依然是黑色，则说明不建议配置主色调
            paraMap.put("auto_color", false);
            //是否需要透明底色， is_hyaline 为true时，生成透明底色的小程序码
            paraMap.put("is_hyaline", false);
            //执行post 获取数据流
            byte[] result = HttpClientUtils.doImgPost(url, paraMap);
            //输出图片到页面
            response.setContentType("image/jpg");
            stream = response.getOutputStream();
            stream.write(result);
            stream.flush();
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取ACCESS_TOKEN
     * 官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
     * <p>
     * 需要正确的 appid  和 secret  查看自己的微信开放平台
     */
    public String getAccessToken() {
        //这里需要换成你d的小程序appid
        String appid = "wx141ac029d803ce4c";
        //这里需要换成你的小程序secret
        String appSecret = "bb245ef5f0add972bccd718087b7dd50";
        //获取微信ACCESS_TOKEN 的Url
        String accent_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
        String url = accent_token_url.replace("APPID", appid).replace("APPSECRET", appSecret);
        //发送请求
        String result = HttpClientUtils.doGet(url);
        Map<String, Object> resultMap = (Map<String, Object>) JsonUtil.jsonToMap(result);
        System.out.println("access_token------>" + resultMap.get("access_token").toString());
        return resultMap.get("access_token").toString();
    }


}
